﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace XDesigner.AppFramework.WinForms
{
    public class DomTreeProvider
    {
        public DomTreeProvider()
        {
        }

        private object _BindControl = null;

        public object BindControl
        {
            get { return _BindControl; }
            set { _BindControl = value; }
        }
         

        public virtual DomTreeEventStyle SupportEvents
        {
            get
            {
                DomTreeEventStyle style = DomTreeEventStyle.None;
                if (GetChildInstances != null)
                {
                    style = style | DomTreeEventStyle.GetChildInstances;
                }
                if (GetNodeStates != null)
                {
                    style = style | DomTreeEventStyle.GetNodeStates;
                }
                //if (IsChildInstancesLoaded != null)
                //{
                //    style = style | DomTreeEventStyle.IsChildInstancesLoaded;
                //}
                return style;
            }
        }
         
        //public event DomTreeEventHandler SupportChildInstances = null;
        //public virtual bool OnSupportChildInstances(object instance)
        //{
        //    if (SupportChildInstances != null)
        //    {
        //        DomTreeEventArgs args = new DomTreeEventArgs();
        //        args.Provider = this;
        //        args.BindControl = this.BindControl;
        //        args.Style = DomTreeEventStyle.SupportChildInstances ;
        //        args.ParentInstance = instance;
        //        SupportChildInstances(this, args);
        //        if (args.Result == null)
        //        {
        //            return false;
        //        }
        //        return Convert.ToBoolean(args.Result);
        //    }
        //    return false ;
        //}

        //public event DomTreeEventHandler IsChildInstancesLoaded = null;
        //public virtual bool OnIsChildInstancesLoaded(object parentInstance)
        //{
        //    if (IsChildInstancesLoaded != null)
        //    {
        //        DomTreeEventArgs args = new DomTreeEventArgs();
        //        args.Provider = this;
        //        args.BindControl = this.BindControl;
        //        args.Style == DomTreeEventStyle.IsChildInstancesLoaded;
        //        args.ParentInstance = parentInstance;
        //        IsChildInstancesLoaded(this, args);
        //        if (args.Result is bool)
        //        {
        //            return (bool)args.Result;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //}

        public event DomTreeEventHandler GetParentInstnace = null;
        public virtual object OnGetParentInstance(object instance)
        {
            if (GetParentInstnace != null)
            {
                DomTreeEventArgs args = new DomTreeEventArgs();
                args.Provider = this;
                args.BindControl = this.BindControl;
                args.Style = DomTreeEventStyle.GetParentInstance;
                args.Instance = instance;
                GetParentInstnace(this, args);
                return args.Result;
            }
            return null;
        }

        public event DomTreeEventHandler GetChildInstances = null;
        public virtual System.Collections.IList OnGetChildInstances(object parentInstance)
        {
            if (GetChildInstances != null)
            {
                DomTreeEventArgs args = new DomTreeEventArgs();
                args.Provider = this;
                args.BindControl = this.BindControl;
                args.Style = DomTreeEventStyle.GetChildInstances;
                args.ParentInstance = parentInstance;
                GetChildInstances(this, args);
                return args.Result as IList ;
            }
            return null;
        }

        public event DomTreeEventHandler GetNodeStates = null;
        public virtual DomTreeEventArgs OnGetNodeStates(object parentInstance, object instance)
        {
            if (GetNodeStates != null)
            {
                DomTreeEventArgs args = new DomTreeEventArgs();
                args.Provider = this;
                args.BindControl = this.BindControl;
                args.Style = DomTreeEventStyle.GetNodeStates;
                args.ParentInstance = parentInstance;
                args.Instance = instance;
                GetNodeStates(this, args);
                return args;
            }
            return null;
        }

        public virtual void EnumerateTree( object rootInstance , DomTreeEventHandler callBack )
        {
            if (rootInstance == null)
            {
                throw new ArgumentNullException("rootInstance");
            }
            if (callBack == null)
            {
                throw new ArgumentNullException("callBack");
            }
            InnerEnumerateTree(rootInstance, callBack);
        }

        private bool InnerEnumerateTree( object rootInstance , DomTreeEventHandler callBack )
        {
            DomTreeEventArgs args = new DomTreeEventArgs();
            args.Provider = this;
            args.BindControl = this.BindControl;
            args.Style = DomTreeEventStyle.Enumerate ;
            args.ParentInstance = rootInstance;
            args.Instance = rootInstance;
            callBack( this , args);
            if (args.Cancel)
            {
                return false;
            }
            IList list = OnGetChildInstances(rootInstance);
            if (list != null)
            {
                foreach (object instance in list)
                {
                    if (InnerEnumerateTree(instance, callBack) == false)
                    {
                        return false;
                    }
                }//foreach
            }
            return true;
        }

        public bool ChangeParent(object instance, object oldParentInstance, object newParentInstance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }
            bool result = false;
            if (oldParentInstance != null)
            {
                IList list = OnGetChildInstances(oldParentInstance);
                if (list.Contains(instance))
                {
                    list.Remove(instance);
                    result = true;
                }
            }
            if (newParentInstance != null)
            {
                IList list = OnGetChildInstances(newParentInstance);
                if (list.Contains(instance) == false)
                {
                    list.Add(instance);
                    return true;
                }
            }
            return result;
        }

    }

    public delegate void DomTreeEventHandler( object sender , DomTreeEventArgs args );

    public class DomTreeEventArgs : System.EventArgs
    {

        public DomTreeEventArgs()
        {
        }

        private object _BindControl = null;

        public object BindControl
        {
            get { return _BindControl; }
            set { _BindControl = value; }
        }
         

        private DomTreeProvider _Provider = null;

        public DomTreeProvider Provider
        {
            get { return _Provider; }
            set { _Provider = value; }
        }

        private DomTreeEventStyle _Style = DomTreeEventStyle.None ;

        public DomTreeEventStyle Style
        {
            get { return _Style; }
            set { _Style = value; }
        }

        private object _ParentInstance = null;

        public object ParentInstance
        {
            get { return _ParentInstance; }
            set { _ParentInstance = value; }
        }

        private object _Instance = null;

        public object Instance
        {
            get { return _Instance; }
            set { _Instance = value; }
        }


        private bool _HasChildInstances = true;

        public bool HasChildInstances
        {
            get { return _HasChildInstances; }
            set { _HasChildInstances = value; }
        }

        private int _ImageIndex = -1;

        public int ImageIndex
        {
            get { return _ImageIndex; }
            set { _ImageIndex = value; }
        }

        private System.Drawing.Image _Image = null;

        public System.Drawing.Image Image
        {
            get { return _Image; }
            set { _Image = value; }
        }

        private string _Text = null;

        public string Text
        {
            get { return _Text; }
            set { _Text = value; }
        }

        private object _Result = null;

        public object Result
        {
            get { return _Result; }
            set { _Result = value; }
        }

        private bool _Cancel = false;

        public bool Cancel
        {
            get { return _Cancel; }
            set { _Cancel = value; }
        }
    }

    [Flags()]
    public enum DomTreeEventStyle
    {
        None = 0 ,
        GetChildInstances =1,
        GetNodeStates = 2 ,
        Enumerate = 4,
        IsChildInstancesLoaded = 8 ,
        GetParentInstance = 16 ,
        All = 0xffffff
    }
}
